package com.infore.authorityManagement.service.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import javax.transaction.Transactional;

import org.apache.commons.lang.StringUtils;
import org.hibernate.Criteria;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import com.infore.authorityManagement.entity.SysAppInfo;
import com.infore.authorityManagement.entity.SysPermission;
import com.infore.authorityManagement.repository.ISysAppInfoRepository;
import com.infore.authorityManagement.service.ISysAppInfoService;
import com.infore.authorityManagement.util.Page;
import com.infore.authorityManagement.util.PageUtil;
import com.infore.authorityManagement.util.UUIDGenerator;

/**
 * 应用系统接口服务
 * @author cys
 *
 */
@Service
@Transactional
public class SysAppInfoServiceImpl implements ISysAppInfoService {
    
    @Autowired
    private ISysAppInfoRepository appInfoRepository;
    
    @Override
    public SysAppInfo getSysAppInfoById(String id) {
        return appInfoRepository.findById(id).orElse(null);
    }
    
    private Specification<SysAppInfo> createSpecification(SysAppInfo sysAppInfo) {
        Specification<SysAppInfo> specification = new Specification<SysAppInfo>() {
            @Override
            public Predicate toPredicate(Root<SysAppInfo> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
                List<Predicate> predicates = new ArrayList<>();
                String appName = sysAppInfo.getAppName();
                Integer appType = sysAppInfo.getAppType();
                if (!StringUtils.isBlank(appName)) {
                    predicates.add(cb.like(root.get("appName"), "%"+appName+"%"));
                }
                String appCode = sysAppInfo.getAppCode();
                if (!StringUtils.isBlank(appCode)) {
                    predicates.add(cb.like(root.get("appCode"), "%"+appCode+"%"));
                }
                if (appType != null) {
                    predicates.add(cb.equal(root.get("appType"), appType));
                }
                Predicate[] p = new Predicate[predicates.size()];
                query.where(cb.and(predicates.toArray(p)));
              //  query.orderBy(cb.asc(root.get("seqNum")));
                return query.getRestriction();
            }
        };
        return specification;
    }

    @Override
    public List<SysAppInfo> getSysAppInfos(SysAppInfo sysAppInfo) {
        Specification<SysAppInfo> specification = createSpecification(sysAppInfo);
        return appInfoRepository.findAll(specification);
    }

    @Override
    public Page<SysAppInfo> getSysAppInfosForPage(SysAppInfo sysAppInfo, Integer pageSize, Integer pageNo) {
        Specification<SysAppInfo> specification = createSpecification(sysAppInfo);
        PageRequest pageable = PageRequest.of(pageNo-1, pageSize);
        return PageUtil.pageConvert(appInfoRepository.findAll(specification, pageable));
    }

    @Override
    public Map<String, Object> addSysAppInfo(SysAppInfo sysAppInfo) {
        Map<String, Object> map = new HashMap<String, Object>();
        String appName = sysAppInfo.getAppName();
        SysAppInfo sysAppInfo_ = appInfoRepository.findByAppName(appName);
        if (sysAppInfo_ != null) {
            map.put("resultIdt", -1);
            return map;
        }
        String appId = UUIDGenerator.getUUID();
        sysAppInfo.setAppId(appId);
        try {
            appInfoRepository.saveAndFlush(sysAppInfo);
        } catch (Exception ex) {
            map.put("resultIdt", -2);
            return map;
        }
        map.put("resultIdt", 0);
        map.put("appId", appId);
        return map;
    }

    @Override
    public int updateSysAppInfo(SysAppInfo sysAppInfo) {
        SysAppInfo appInfo = getSysAppInfoById(sysAppInfo.getAppId());
        String oldAppCode = appInfo.getAppCode();
        if (appInfo == null) {
            return -3;
        }
        
        String appName = sysAppInfo.getAppName();
        SysAppInfo sysAppInfo_ = appInfoRepository.findByAppName(appName);
        if (sysAppInfo_ != null && !sysAppInfo_.getAppId().equals(sysAppInfo.getAppId())) {
        	return -1;
        }
        if (appName != null && !appName.trim().isEmpty()) {
            appInfo.setAppName(sysAppInfo.getAppName());
        }
        
        String appCode = sysAppInfo.getAppCode();
        if (appCode != null && !appCode.trim().isEmpty()) {
            appInfo.setAppCode(sysAppInfo.getAppCode());
        }

        String appPort = sysAppInfo.getAppPort();
        if (!StringUtils.isBlank(appPort)) {
            appInfo.setAppPort(sysAppInfo.getAppPort());
        }

        String description = sysAppInfo.getDescription();
        if (!StringUtils.isBlank(description)) {
            appInfo.setDescription(description);
        }
        try {
            appInfoRepository.flush();
            if (!StringUtils.isBlank(appCode)) {
                //是否直接更新权限服务
            	String sql = "update sys_permission set app_code = '" + appCode + "' where app_code = '" + oldAppCode + "'";
            	//sysAppInfoDao.createSQLQuery(sql).executeUpdate();
            }
        } catch (Exception ex) {
            ex.printStackTrace();
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); //手动开启事务回滚
            return -2;
        }
        return 0;
    }

    @Override
    public int deleteSysAppInfo(String id) {
        SysAppInfo sysAppInfo = getSysAppInfoById(id);
        if (sysAppInfo == null) {
            return -1;
        }
        try {
            appInfoRepository.delete(sysAppInfo);
        } catch (Exception ex) {
            ex.printStackTrace();
            return -2;
        }
        return 0;
    }

    @Override
    public List<SysAppInfo> getSysAppInfosById(List<String> appId, String keyword) {
        if (appId == null || appId.size() == 0) {
            return new ArrayList<>();
        }
        if(keyword == null) {
            keyword ="";
        }
        return appInfoRepository.findByAppIdInAndAppNameLike(appId, keyword);
    }

}
